#ifndef LD2451_h
#define LD2451_h

#include "Arduino.h"
#include <vector>

class LD2451 {
public:
    // 目标信息结构体
    struct Target {
        int angle;          // 角度（度）
        int distance;       // 距离（米）
        int speed;          // 速度（km/h）
        bool isApproaching; // 是否靠近雷达（true=靠近，false=远离）
        int snr;            // 信噪比

        Target() : angle(0), distance(0), speed(0), isApproaching(false), snr(0) {}
    };

    // 配置参数结构体
    struct Config {
        uint8_t minDistance;      // 最近检测距离 (0x0A-0xFF, 单位:米)
        uint8_t detectionDirection; // 运动方向设置 (0:只检测远端, 1:只检测靠近, 2:均检测)
        uint8_t minSpeed;         // 最小运动速度 (0x00-0x78, 单位:km/h)
        uint8_t noTargetDelay;    // 无目标延迟时间 (0x00-0xFF, 单位:秒)

        Config() : minDistance(0x64), detectionDirection(2), minSpeed(5), noTargetDelay(2) {} // 默认值
    };

    // 灵敏度参数结构体
    struct Sensitivity {
        uint8_t triggerCount;    // 累积有效触发次数 (1-10)
        uint8_t snrThreshold;    // 信噪比阈值等级 (3-8, 值越大灵敏度越差)

        Sensitivity() : triggerCount(1), snrThreshold(4) {} // 默认值
    };

    // 构造函数
    LD2451(HardwareSerial& serial);

    // 初始化串口
    void begin(uint32_t baudrate = 115200);

    // 处理接收到的串口数据（需在loop中频繁调用）
    void processSerial();

    // 获取解析后的目标列表
    const std::vector<Target>& getTargets() const;

    // 获取最后有效帧的时间戳
    unsigned long getLastFrameTime() const;

    // 获取目标数量
    uint8_t getTargetCount() const;

    // ================ 配置命令接口 ================
    
    // 使能配置模式 (必须先调用)
    bool enableConfigMode();
    
    // 结束配置模式
    bool endConfigMode();
    
    // 设置目标检测参数
    bool setDetectionParams(const Config& config);
    
    // 读取目标检测参数
    bool readDetectionParams(Config& config);
    
    // 设置灵敏度参数
    bool setSensitivityParams(const Sensitivity& sens);
    
    // 读取灵敏度参数
    bool readSensitivityParams(Sensitivity& sens);
    
    // 读取固件版本
    bool readFirmwareVersion(String& version);
    
    // 设置串口波特率 (索引值参考协议)
    bool setBaudRate(uint16_t baudIndex);
    
    // 恢复出厂设置
    bool factoryReset();
    
    // 重启模块
    bool reboot();

private:
    // 解析器状态
    enum FrameState {
        WAITING_HEADER,  // 等待帧头
        READING_LENGTH,   // 读取数据长度
        READING_PAYLOAD,  // 读取有效载荷
        CHECKING_FOOTER   // 检查帧尾
    };

    // 帧头帧尾定义
    static const uint8_t HEADER[4];
    static const uint8_t FOOTER[4];
    static const uint8_t CMD_HEADER[4];
    static const uint8_t CMD_FOOTER[4];

    HardwareSerial* serial_;
    FrameState frameState;
    std::vector<uint8_t> buffer;
    std::vector<Target> targets;
    uint16_t expectedLength;   // 期望的数据长度
    uint16_t bytesRead;        // 已读取字节数
    uint8_t currentTargetCount; // 当前帧目标数量
    unsigned long lastFrameTime; // 最后有效帧时间戳
    bool configEnabled;        // 配置模式是否已使能

    // 处理接收到的字节
    void processData(uint8_t byte);

    // 重置解析器状态
    void reset();

    // 发送命令核心方法
    bool sendCommand(uint16_t cmd, const std::vector<uint8_t>& data = {}, 
                    std::vector<uint8_t>& response = dummyResponse_, 
                    unsigned long timeout = 200);
    
    // 等待ACK响应
    bool waitForACK(uint16_t cmd, std::vector<uint8_t>& response, unsigned long timeout);
    
    // 静态虚拟响应对象用于无响应命令
    static std::vector<uint8_t> dummyResponse_;
};

#endif